package com.yanqu.road.server.manger.config;

import com.yanqu.road.logic.bussiness.config.SacrificeBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.config.sacrifice.SacrificeBoss;
import com.yanqu.road.entity.config.sacrifice.SacrificeDetail;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.enums.ePatronsSkillType;
import com.yanqu.road.entity.enums.eSkillType;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.entity.player.UserPatronsSkill;
import com.yanqu.road.entity.sacrifice.SacrificeDamageRankReward;
import com.yanqu.road.entity.sacrifice.SacrificeTimeData;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.servercenter.TitleInfo;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class SacrificeConfigMgr extends TempMgr {

    private static Logger logger = LogManager.getLogger(SacrificeConfigMgr.class.getName());

    private static Map<Integer, SacrificeBoss> sacrificeBossMap;

    private static int maxBossLv;

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean reloadConfig() {
        sacrificeBossMap = SacrificeBussiness.getSacrificeBossMap();
        if(sacrificeBossMap.size() <= 0){
            return false;
        }
        int maxLv = 0;
        for(SacrificeBoss boss : sacrificeBossMap.values()){
            if(boss.getLevel() > maxLv){
                maxLv = boss.getLevel();
            }
        }
        maxBossLv = maxLv;
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    public static boolean isSacrificeSystemOpenTime(){
        ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
        int days = DateHelper.calc2DateTDOADays(new Date(serverInfo.getOpenTime() * 1000), new Date());
        return days >= GameConfig.SEVER_OPEN_AFTER_DAYS_OPEN_SACRIFICE;
    }

    //需要初始化大龙血量
    public static boolean isFirstInitSacrificeBloodTime(){
        ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
        int days = DateHelper.calc2DateTDOADays(new Date(serverInfo.getOpenTime() * 1000), new Date());
        return days <= GameConfig.SEVER_OPEN_AFTER_DAYS_OPEN_SACRIFICE;
    }

    public static boolean isInSacrificeAttackBossTime(){
        SacrificeTimeData sacrificeTimeData = ConfigMgr.getSacrificeTimeData();
        if(null == sacrificeTimeData){
            return false;
        }
        Calendar calNow = Calendar.getInstance();
        int hour =  calNow.get(Calendar.HOUR_OF_DAY);
        int minute = calNow.get(Calendar.MINUTE);
        if(hour > sacrificeTimeData.getStartHour()){
            if(hour < sacrificeTimeData.getEndHour()){
                return true;
            }else if(hour == sacrificeTimeData.getEndHour()){
                return minute < sacrificeTimeData.getEndMinute();
            }
        }else if(hour == sacrificeTimeData.getStartHour()){
            if(minute >= sacrificeTimeData.getStarMinute()){
                if(hour < sacrificeTimeData.getEndHour()){
                    return true;
                }else if(hour == sacrificeTimeData.getEndHour()){
                    return minute < sacrificeTimeData.getEndMinute();
                }
            }
        }
        return false;
    }

    public static boolean isTodaySendSacrificeRewardTime(SacrificeDetail sacrificeDetail){
        boolean result = isAfterSacrificeAttackBossTime();
        if(!result){
            if(null != sacrificeDetail){
                if(sacrificeDetail.getKillBossUserId() > 0 && sacrificeDetail.getKillTime() > 0){
                    if(System.currentTimeMillis() / 1000 > sacrificeDetail.getKillTime() + 300){//当天击杀5分钟后，就可以发奖了
                        return true;
                    }
                }
            }
        }
        return result;
    }

    public static boolean isAfterSacrificeAttackBossTime(){
        SacrificeTimeData sacrificeTimeData = ConfigMgr.getSacrificeTimeData();
        if(null == sacrificeTimeData){
            return false;
        }
        Calendar calNow = Calendar.getInstance();
        int hour =  calNow.get(Calendar.HOUR_OF_DAY);
        int minute = calNow.get(Calendar.MINUTE);
        if(hour > sacrificeTimeData.getEndHour()){
            return true;
        }else if(hour == sacrificeTimeData.getEndHour()){
            return minute >= sacrificeTimeData.getEndMinute();
        }
        return false;
    }

    /**
     * 门客伤害值
     */
    public static BigInteger getPatronsDamage(GamePlayer player, UserPatrons userPatrons){
        BigDecimal ability = new BigDecimal(userPatrons.getAbility());
        double skillAddition = 0;
        PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userPatrons.getPatronsId());
        Map<Integer, UserPatrons> patronsMap = player.getModule(PatronsModule.class).getUserPatronsMap();
        for(UserPatrons patrons : patronsMap.values()){
            for(UserPatronsSkill patronsSkill : patrons.getSkillList()){
                if(patronsSkill.getType() != ePatronsSkillType.Talent.getValue()){
                    continue;
                }
                SkillInfo skillInfo = SkillMgr.getSkillInfo(patronsSkill.getSkillId());
                if(skillInfo.getType() != eSkillType.SacrificeAddDamage.getValue()){
                    continue;
                }
                int param3 = skillInfo.getParamList().get(2);
                if(0 == param3){
                    skillAddition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
                }else if(1 == param3){
                    if(patrons.getPatronsId() == userPatrons.getPatronsId()){
                        skillAddition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
                    }
                }else if(2 == param3){
                    PatronsInfo tempPatronsInfo = PatronsMgr.getPatronsInfo(patrons.getPatronsId());
                    if(patronsInfo.getOccupation() == tempPatronsInfo.getOccupation()){
                        skillAddition += SkillMgr.getSkillAddition(skillInfo, patronsSkill.getSkillLv());
                    }
                }
            }
        }
        ability = ability.multiply(BigDecimal.valueOf(skillAddition / 1000 + 1)).setScale(0, BigDecimal.ROUND_UP);
        return ability.toBigInteger();
    }

    /**
     * 门客出战次数
     */
    public static int getPatronsMaxSacrificeAttackTimes(GamePlayer player, int patronsId){
        int times = GameConfig.SACRIFICE_PATRONS_DEFAULT_ATTACK_TIMES;
        return times;
    }

    public static SacrificeBoss getSacrificeBoss(int level){
        return sacrificeBossMap.get(level);
    }

    /**
     * 获取攻击boss奖励
     */
    public static Property getSacrificeAttackBossReward(GamePlayer player, UserPatrons userPatrons){
        Property reward = new Property();
        List<Integer> paramList = ConfigMgr.getSacrificeAttackRewardParam();
        TitleInfo titleInfo = TitleMgr.getTitleInfo(player.getTitleId());
        //阅历
        BigInteger value = BigDecimal.valueOf(userPatrons.getLevel()).multiply(BigDecimal.valueOf((double)paramList.get(0) / 1000)).
                multiply(BigDecimal.valueOf(titleInfo.getChildTrainAddExp())).setScale(0, BigDecimal.ROUND_UP).toBigInteger();
        reward.addProperty(GameConfig.GAME_MONEY_PATRONS_EXP, value);
        //银两
        value = BigDecimal.valueOf(userPatrons.getLevel()).multiply(BigDecimal.valueOf((double)paramList.get(1) / 1000)).
                multiply(new BigDecimal(player.getUserInfo().getEarnSpeed())).setScale(0, BigDecimal.ROUND_UP).toBigInteger();
        reward.addProperty(GameConfig.GAME_MONEY_SILVER, value);
        return reward;
    }

    public static SacrificeBoss getSacrificeBoss(SacrificeDetail lastSacrificeDetail, SacrificeDetail sacrificeDetail){
        int level = 1;
        List<Integer> paramList = ConfigMgr.getSacrificeBossLevelParam();
        if(null != lastSacrificeDetail){
            if(isFirstInitSacrificeBloodTime()) {//初始化大龙
                int tempLv = maxBossLv;
                BigInteger tempAbility = new BigDecimal(sacrificeDetail.getActiveAbility()).multiply(BigDecimal.valueOf((double)paramList.get(0) / 1000)).
                        setScale(0, BigDecimal.ROUND_UP).toBigInteger();
                do {
                    SacrificeBoss sacrificeBoss = getSacrificeBoss(tempLv);
                    if(null == sacrificeBoss){
                        break;
                    }
                    if(sacrificeBoss.getBlood().compareTo(tempAbility) < 0){
                        level = tempLv;
                        break;
                    }
                    tempLv--;
                }while (true);
//                if(level < GameConfig.SACRIFICE_DEFAULT_LEVEL){
//                    level = GameConfig.SACRIFICE_DEFAULT_LEVEL;
//                }
            }else {//判断大龙升降级
                if(lastSacrificeDetail.getCurrentBlood().compareTo(BigInteger.ZERO) > 0 ||
                    !isInMinuteKillBoss(lastSacrificeDetail, paramList.get(1))){
                    //|| lastSacrificeDetail.getInTimeAbility().compareTo(new BigDecimal(lastSacrificeDetail.getTotalBlood()).
                    //        multiply(BigDecimal.valueOf((double) paramList.get(2) / 1000)).setScale(0, BigDecimal.ROUND_UP).toBigInteger()) < 0){
                    //v2  2020-11-12   条件：1、昨日未被击杀或者击杀超过50分钟（参数2）  2、昨日活动期间活跃玩家总赚钱  <  昨日boss血量一定比例(参数3)； 满足一个就降级
                    level = lastSacrificeDetail.getBossLevel() - 1;
                } else if(isInMinuteKillBoss(lastSacrificeDetail, paramList.get(3)) &&
                        lastSacrificeDetail.getInTimeAbility().compareTo(new BigDecimal(lastSacrificeDetail.getTotalBlood()).multiply(BigDecimal.valueOf((double) paramList.get(4) / 1000)).
                                setScale(0, BigDecimal.ROUND_UP).toBigInteger()) > 0){
                    //v2 条件：1、昨日boss在25分钟内被击杀（参数4） 2、昨日活动期间活跃玩家总赚钱  >  昨日boss血量一定比例(参数5)； 2个条件均满足就升级
                    if(isInMinuteKillBoss(lastSacrificeDetail, 5)){//如果5分钟内击杀，升2级
                        level = lastSacrificeDetail.getBossLevel() + 2;
                    }else {
                        level = lastSacrificeDetail.getBossLevel() + 1;
                    }
                }else {
                    level = lastSacrificeDetail.getBossLevel();
                }
            }
        }else {
            level = GameConfig.SACRIFICE_DEFAULT_LEVEL;
        }
        if(level < 1){
            level = 1;
        }
        if(level > maxBossLv){
            level = maxBossLv;
        }
        return getSacrificeBoss(level);
    }

    /**
     * 是否5分钟内击杀boss
     */
    public static boolean isFiveMinuteKillBoss(SacrificeDetail lastSacrificeDetail){
        SacrificeTimeData sacrificeTimeData = ConfigMgr.getSacrificeTimeData();
        long tempTime = DateHelper.HOUR_SECONDS * sacrificeTimeData.getStartHour() + DateHelper.MINUTE_SECONDS * sacrificeTimeData.getStarMinute() +
                GameConfig.SACRIFICE_KILL_BOSS_UPGRADE_LEVEL_MINUTE;
        //5分钟内boss被击杀
        return lastSacrificeDetail.getKillTime() > 0 && lastSacrificeDetail.getKillTime() - lastSacrificeDetail.getDateMark() < tempTime;
    }

    /**
     * （多少分钟内）是否击杀boss
     */
    public static boolean isInMinuteKillBoss(SacrificeDetail lastSacrificeDetail, int minute){
        SacrificeTimeData sacrificeTimeData = ConfigMgr.getSacrificeTimeData();
        long tempTime = DateHelper.HOUR_SECONDS * sacrificeTimeData.getStartHour() + DateHelper.MINUTE_SECONDS * sacrificeTimeData.getStarMinute() +
                minute * DateHelper.MINUTE_SECONDS;
        //多少分钟内boss被击杀
        return lastSacrificeDetail.getKillTime() > 0 && lastSacrificeDetail.getKillTime() - lastSacrificeDetail.getDateMark() < tempTime;
    }

    /**
     * 获取伤害排行奖励
     */
    public static Property getSacrificeDamageReward(int rank){
        List<SacrificeDamageRankReward> rankRewardList = ConfigMgr.getSacrificeDamageRankRewardList();
        for(SacrificeDamageRankReward rankReward : rankRewardList){
            if(rank >= rankReward.getMinRank() && rank <= rankReward.getMaxRank()){
                return new Property(rankReward.getReward());
            }
        }
        return null;
    }

    public static int getSacrificeDamageMaxRank(){
        return ConfigMgr.getSacrificeDamageMaxRank();
    }
}
